用 PHP 與 MySQL 學習後端基礎(三)實作 API


Posted by ericcch24 on 2020-10-16

PHP 與 API 拿取資料的差異

PHP

  1. 把資料利用 SQL 指令拿出來
  2. 把資料 HTML 跟結合(UI)再一起
  3. 回傳 HTML

browser render: 留言板
==這時候是 server-side render,在伺服器端就把資料跟 HTML 綁好回傳,所以瀏覽器接收到的資料已經有介面,就可以直接顯示。==

API

  1. 把資料拿出來
  2. 變成某種格式(JSON),因為沒有與 HTML 結合所以不會有介面,只是資料
  3. 回傳

透過 JS render => 顯示資料
==資料回傳時 HTML 還是空的,因此瀏覽器在拿到後端資料還需要經過 JS render 來動態顯示資料。==

參考資料:跟著小明一起搞懂技術名詞:MVC、SPA 與 SSR


用 PHP 實作 API:列出所有文章

  // 以上都與 index.php 相同
  // 將 SQL 抓的資料以陣列形式印出
  while($row = $result->fetch_assoc()) {
    array_push($comments, array(
      "id" => $row["id"], 
      "username" => $row["username"],
      "nickname" => $row["nickname"],
      "content" => $row["content"],
      "created_at" => $row["created_at"]
    ));
  }

  // 將陣列轉成 JSON 格式
  $json = array(
    "comments" => $comments
  );

  $response = json_encode($json);
  // 編碼讓瀏覽器可以讀取
  header('Content-type:application/json;charset=utf-8');
  echo $response;

用 PHP 實作 API:新增文章

<?php
  require_once('conn.php');

  header('Content-type:application/json;charset=utf-8');

  if (empty($_POST['content'])) 
  {
    $json = array(
      "ok" => false,
      "message" => "Please input content"
    );

    $response = json_encode($json);
    echo $response;
    die();
  }

  $username = $_POST['username'];
  $content = $_POST['content'];


  $sql = "INSERT INTO ericcch24_comments(username, content) VALUES(?, ?)";
  $stmt = $conn->prepare($sql);
  $stmt->bind_param('ss', $username, $content);
  $result = $stmt->execute();
  if (!$result) {
    $json = array(
      "ok" => false,
      "message" => die($conn->error)
    );

    $response = json_encode($json);
    echo $response;
    die();
  }

  $json = array(
    "ok" => true, //新增成功時為 ok 狀態
    "message" => "Success"
  );

  $response = json_encode($json);
  echo $response;
?>

透過前端串接 API

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>留言板</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <header class="warning">
    <strong>注意!本站為練習用網站,因教學用途刻意忽略資安的實作,註冊時請勿使用任何真實的帳號或密碼。</strong>
  </header>
  <main class="board">

    <h1 class="board__title">Comments</h1>


    <form class="board__new-comment-form">
      <textarea name="content" rows="5"></textarea>
      <input class="board__submit-btn" type="submit" />
    </form>
    <div class="board__hr"></div>
      <section>

      </section>
  </main>
</body>
<script>
  //用 ajax 取得資料後放到 html 上面
  let request = new XMLHttpRequest();
  request.open('GET', 'api_comments.php', true);

  request.onload = function() {
    if (this.status >= 200 && this.status < 400) {
      // Success!
      let resp = this.response;
      let json = JSON.parse(resp);
      let comments = json.comments;

      for (let i = 0; i < comments.length; i++) {
        let comment = comments[i];
        let div = document.createElement('div');
        div.classList.add('card');
        div.innerHTML = `
              <div class="card__avatar"></div>
              <div class="card__body">
                <div class="card__info">
                  <span class="card__author">
                    ${comment.nickname}(@${comment.username})
                  </span>
                  <span class="card__time">
                    ${comment.created_at}
                  </span>
                </div>
                <p class="card__content">${encodeHTML(comment.content)}</p>
              </div> 
        `
        document.querySelector('section').appendChild(div);
      }
    }
  };



  request.send();

  let form = document.querySelector('.board__new-comment-form');
  form.addEventListener('submit', function(e) {
    e.preventDefault();
    let content = document.querySelector('textarea[name=content]').value;
    let request = new XMLHttpRequest();
    request.open('POST', 'api_add_comment.php', true);
    request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    request.send("username=ooo&content=" + encodeURIComponent(content));
    request.onload = function() {
      if (this.status >= 200 && this.status < 400) {
        let resp = this.response;
        let json = JSON.parse(resp)
          if (json.ok) {
            location.reload() // 有成功新增留言就重新整理
          } else {
            alert(json.message)
          }
      }
    }
  })
  function encodeHTML(s) {
        return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/"/g, '&quot;');
  }
</script>
</html>

tags: Week12

#week12







Related Posts

871. Minimum Number of Refueling Stops

871. Minimum Number of Refueling Stops

React Next.js and Material UI(MUI)

React Next.js and Material UI(MUI)

透過 EventBus 解決 TransactionTooLargeException 問題

透過 EventBus 解決 TransactionTooLargeException 問題


Comments